package davidlauzon.activerecord;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import davidlauzon.activerecord.connection.ConnectionAdapter;
import davidlauzon.activerecord.connection.SqliteAdapter;
import davidlauzon.activerecord.models.DB;
import davidlauzon.activerecord.models.Person;
import davidlauzon.activerecord.nodes.field.Field;
import davidlauzon.activerecord.recordset.RecordSet;

public class ActiveRecordTest extends AbstractTestCase
{
    /*********************************************************************************************
     * VARIABLES
     *********************************************************************************************/
    private ConnectionAdapter _adapter;
    
    
    
    /*********************************************************************************************
     * TEST METHODS
     *********************************************************************************************/
    @Override
    protected void setUp() {
        try {
            _adapter = new SqliteAdapter("test.db");
            DB.getInstance().setConnection( _adapter );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /*********************************************************************************************
     * TEST METHODS
     *********************************************************************************************/
    public void testActiveRecord() {
        try {
            printRecords();
            
            // Create a record
            Map<Field, Object> values = new HashMap<Field, Object>();
            values.put(Person.NAME, "Priya Rey");
            values.put(Person.AGE,  32);
            values.put(Person.SIZE, 42.2436f);
            
            Person person = Person.create(values);
            log("testActiveRecord", "Should have created (new=" + person.isNewRecord() + ") a Person: " + person.toString());
            printRecords();
            
            // Updating
            person.set(Person.SIZE, 69.69f);
            if (person.save())
                log("testActiveRecord", "Person updated.");
            else
                log("testActiveRecord", "Person NOT updated.");
            printRecords();
            
            // Deleting
            if (person.delete())
                log("testActiveRecord", "Person deleted.");
            else
                log("testActiveRecord", "Person NOT deleted.");
            printRecords();
            
            // FIXME : does not work for mysql
            // Dropping table
//            DB.PEOPLE_TABLE.drop();
//            logSql(DB.PEOPLE_TABLE.dropAsSqlString(), 0);
//            try {
//                printRecords();
//                log("testActiveRecord", "Table NOT dropped.");
//            } catch (SQLException e) {
//                log("testActiveRecord", "Table dropped.");
//            }
            
            // Creating table
//            DB.PEOPLE_TABLE.create();
//            logSql(DB.PEOPLE_TABLE.createAsSqlString(), 0);
//            try {
//                printRecords();
//                log("testActiveRecord", "Table created.");
//            } catch (SQLException e) {
//                log("testActiveRecord", "Table NOT created.");
//            }
        } catch (SQLException e) {
            e.printStackTrace();
        } 
    }
    
    
    public void testActiveRecordSelect() throws SQLException {
        log("\n\ntestActiveRecordSelect", "Testing SELECT queries");
        log("SQL", Person.find("id > 1").toSql() );
        
        RecordSet set = Person.find("\"id\" > 1").query();
        
        long   id;
        String name;
        float  size;
        int    age;
        
        while (set.next()) {
            id    = set.getLong(0);
            name  = set.getString(1);
            size  = set.getFloat(2);
            age   = set.getInt(3);
            System.out.println("\t=> #" + id + " " + name + ": " + size + " ; " + age);
        }
    }
    
    
    /*********************************************************************************************
     * INTERNAL METHODS
     *********************************************************************************************/

    protected void log(String funcName, Object message) {
        System.out.println(getClass().getSimpleName() + "::" + funcName + "() " + message);
    }
    

    protected int printRecords() throws SQLException {
        RecordSet set;
        int size = 0;
        
        long   l;
        String s;
        float  f;
        int    i;
        
//        log("printRecords", "adapter: " + getAdapter());
//        log("printRecords", "constant: " + Constants.SELECT_ALL_PEOPLE);
        set = getAdapter().executeQuery( Constants.SELECT_ALL_PEOPLE);
        
        while ( set.next() ) {
            l = set.getLong(0);
            s = set.getString(1);
            f = set.getFloat(2);
            i = set.getInt(3);
            size++;
            log("listing db records", "\t=> #" + l + " " + s + ": " + f + " ; " + i);
        }
        set.close();
        
        return size;
    }

    @Override
    protected ConnectionAdapter getAdapter()
    {
        return _adapter;
    }

}
